什么是 Pthread

POSIX线程,英语:POSIX Threads,常被缩写为 Pthreads ,是 POSIX 的线程标准,定义了创建和操纵线程的一套 API

实现POSIX 线程标准的库常被称作 Pthreads ,一般用于 Unix-likePOSIX 系统,如 Linux、Solaris。但是 Microsoft Windows 上的实现也存在,例如直接使用 Windows API 实现的第三方库 pthreads-w32 ,而利用 Windows 的 SFU/SUA 子系统,则可以使用微软提供的一部分原生 POSIX API

Pthreads 定义了一套C语言的类型、函数与常量,它以 pthread.h 头文件和一个线程库实现

Pthreads API 中大致共有 100 个函数调用,全都以 “pthread_” 开头,并可以分为四类:

  1. 线程管理,例如创建线程,等待(join)线程,查询线程状态等。
  2. 互斥锁(Mutex):创建、摧毁、锁定、解锁、设置属性等操作
  3. 条件变量(Condition Variable):创建、摧毁、等待、通知、设置与查询属性等操作
  4. 使用了互斥锁的线程间的同步管理

POSIX 的 SemaphoreAPI 可以和 Pthreads 协同工作,但这并不是 Pthreads 的标准。因而这部分 API 是以 “sem_” 打头,而非 “pthread_”

学习记录

l1

pthread_create()

  • 创建线程

pthread_join()

  • 销毁线程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <pthread.h>

using namespace std;

void* hello(void* index) {
printf("Hello Pthread from thread %u\n", pthread_self());
return nullptr;
}

int main() {
int n;
cout << "Enter n : ";
cin >> n;

pthread_t* ths = new pthread_t[n];

int status;
for (int i = 0; i < n; i++) {
status = pthread_create(ths + i, nullptr, hello, &i);
if (status != 0) {
return -1;
}
}

for (int i = 0; i < n; i++) {
pthread_join(ths[i], nullptr);
}

delete[] ths;

return 0;
}

l2

pthread_attr_init()

  • 获取当前线程属性

pthread_attr_getdetachstate()

  • 获取当前线程分离状态

pthread_attr_getschedpolicy()

  • 获取当前线程调度状态

pthread_attr_getschedparam()

  • 获取当前线程优先级状态

pthread_attr_getinheritsched()

  • 获取当前线程继承性

pthread_attr_getscope()

  • 获取当前线程作用域

pthread_attr_getstackaddr()

  • 获取当前线程栈地址

pthread_attr_getstacksize()

  • 获取当前线程栈大小
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <pthread.h>

using namespace std;

void* thread_info(void* arg) {
printf("Thread id : %u\n", pthread_self());
pthread_attr_t attr;
pthread_attr_init(&attr);
int detachstate, schedpolicy, inheritsched, scope;
sched_param schedparam;
void* stackaddr;
size_t stacksize;
pthread_attr_getdetachstate(&attr, &detachstate);
pthread_attr_getschedpolicy(&attr, &schedpolicy);
pthread_attr_getschedparam(&attr, &schedparam);
pthread_attr_getinheritsched(&attr, &inheritsched);
pthread_attr_getscope(&attr, &scope);
pthread_attr_getstackaddr(&attr, &stackaddr);
pthread_attr_getstacksize(&attr, &stacksize);
printf("Detachstate : %d\n", detachstate);
printf("Schedpolicy : %d\n", schedpolicy);
printf("Schedparam : %d\n", schedparam);
printf("Inheritsched : %d\n", inheritsched);
printf("Scope : %d\n", scope);
printf("Stackaddr : %d\n", stackaddr);
printf("Stacksize : %d\n", stacksize);
return nullptr;
}

int main() {
pthread_t th;
if (pthread_create(&th, nullptr, thread_info, nullptr) != 0)
return -1;

pthread_join(th, nullptr);

return 0;
}

l3

pthread_mutex_init()

  • 初始化互斥锁

pthread_mutex_lock()

  • 互斥锁上锁

pthread_mutex_unlock()

  • 互斥锁解锁

pthread_mutex_destroy()

  • 销毁互斥锁
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <pthread.h>

using namespace std;

int num_res = 0;
pthread_mutex_t mutex_res;

void* add_res(void* args) {
pthread_mutex_lock(&mutex_res);
for (int i = 0; i < 10000; i++)
num_res++;
pthread_mutex_unlock(&mutex_res);
return nullptr;
}

int main() {
pthread_t ths[100];
pthread_mutex_init(&mutex_res, nullptr);

for (int i = 0; i < 100; i++)
pthread_create(ths + i, nullptr, add_res, nullptr);

for (int i = 0; i < 100; i++)
pthread_join(ths[i], nullptr);

pthread_mutex_destroy(&mutex_res);
cout << num_res << endl;

return 0;
}

l4

sem_init()

  • 初始化信号量

sem_wait()

  • 等待信号

sem_post()

  • 发送单个信号

sem_post_multiple()

  • 发送多个信号

sem_destory()

  • 销毁信号量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <iostream>
#include <pthread.h>
#include <semaphore.h>
#include <windows.h>
#include <string>

using namespace std;

string tot_string = "";
sem_t tot_sem;
bool tot_is_start;

void* set_string(void* args) {
int idx = *(int*)args;
delete args;
printf("thread %d start\n", idx);
sem_wait(&tot_sem);
while (tot_is_start) {
printf("thread %d set string %s\n", idx, tot_string.c_str());
sem_wait(&tot_sem);
}
printf("thread %d exit\n", idx);
return nullptr;
}

int main() {
int n;
cout << "Enter thread num : ";
cin >> n;

pthread_t* ths = new pthread_t[n];
sem_init(&tot_sem, 0, 0);
tot_is_start = true;

for (int i = 0; i < n; i++) {
int* arg = new int;
*arg = i;
pthread_create(ths + i, nullptr, set_string, arg);
}

while (true) {
Sleep(500);
printf("Enter your new string : ");
tot_string = "";
while (tot_string == "")
getline(cin, tot_string);
if (tot_string == "exit")
break;
sem_post(&tot_sem);
}

tot_is_start = false;
for (int i = 0; i < n; i++) {
sem_post_multiple(&tot_sem, n);
pthread_join(ths[i], nullptr);
}

sem_destroy(&tot_sem);

return 0;
}

l5

pthread_rwlock_init()

  • 初始化读写锁

pthread_rwlock_trywrlock()

  • 尝试读锁上锁

pthread_rwlock_tryrdlock()

  • 尝试写锁上锁

pthread_rwlock_unlock()

  • 解锁

pthread_rwlock_destroy()

  • 销毁读写锁
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include <pthread.h>
#include <windows.h>

using namespace std;

pthread_t paper;
pthread_rwlock_t paper_rwlock;

void* write_func(void* args) {
while (true) {
pthread_t th = pthread_self();
pthread_rwlock_trywrlock(&paper_rwlock);
paper = th;
printf("thread %u write %u\n", th, paper);
pthread_rwlock_unlock(&paper_rwlock);
Sleep(500);
}
return nullptr;
}

void* read_func(void* args) {
while (true) {
pthread_rwlock_tryrdlock(&paper_rwlock);
printf("thread %u read %u\n", pthread_self(), paper);
pthread_rwlock_unlock(&paper_rwlock);
Sleep(500);
}
return nullptr;
}

int main(int argc, char** argv) {
int read, write;
cout << "Enter write num : ";
cin >> write;
cout << "Enter read num : ";
cin >> read;

pthread_t* read_ths = new pthread_t[read];
pthread_t* write_ths = new pthread_t[write];
pthread_rwlock_init(&paper_rwlock, nullptr);

for (int i = 0; i < read; i++)
pthread_create(read_ths + i, nullptr, read_func, nullptr);

for (int i = 0; i < write; i++)
pthread_create(write_ths + i, nullptr, write_func, nullptr);

for (int i = 0; i < read; i++)
pthread_join(read_ths[i], nullptr);

for (int i = 0; i < write; i++)
pthread_join(write_ths[i], nullptr);

pthread_rwlock_destroy(&paper_rwlock);
delete[] read_ths;
delete[] write_ths;

return 0;
}